using System;
using Xunit;
using FrameIdentityReq.Frames;
using Exceptions;

namespace test_x
{
    public class TestBaseFrame : BaseFrame
    {

        public TestBaseFrame() : base() { }
        [Fact]
        public void TestName()
        {
            Assert.Equal(5, Buffer.Count);
            Assert.Equal(0, ProtocolVersion.Index);
            Assert.Equal(4, ProtocolVersion.Count);
            Assert.Equal(4, FactoryCode.Index);
            Assert.Equal(4, FactoryCode.Count);
            Assert.Equal(8, FrameType.Index);
            Assert.Equal(5, FrameType.Count);
            Assert.Equal(13, InfoLength.Index);
            Assert.Equal(11, InfoLength.Count);
            Assert.Equal(24, CRC.Index);
            Assert.Equal(16, CRC.Count);

            Assert.Equal(4, ProtocolVersion.Value);
            Assert.Equal(4, FactoryCode.Value);
            Assert.Equal("0x44", $"0x{Buffer[0]:X2}");
            Assert.Equal(FrameTypeEnum.NULL, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            Assert.Equal(0, CRC.Value);
            // UInt16 CRCValue = CrcField.CalculationCRC(Buffer, 0, CRC.IntField.Field.Index);
            // Assert.Equal("0x130", $"0x{CRCValue:X2}");
            // CRC.Value = CRCValue;
            // Assert.Equal("0x130", $"0x{CRC.Value:X2}");
            // CRCValue = CrcField.CalculationCRC(Buffer, 0, CRC.IntField.Field.Index);
            // Assert.Equal("0x130", $"0x{CRCValue:X2}");


            ProtocolVersion.Value = 0x0F;
            FactoryCode.Value = 0x4;
            Assert.Equal(5, Buffer.Count);
            Assert.Equal("0x0F", $"0x{ProtocolVersion.Value:X2}");
            Assert.Equal(4, FactoryCode.Value);
            Assert.Equal(FrameTypeEnum.NULL, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            // Assert.Equal("0x130", $"0x{CRC.Value:X2}");
            // Assert.Equal("0x3230", $"0x{CrcField.CalculationCRC(Buffer, 0, CRC.IntField.Field.Index):X2}");

            Assert.Throws<ExceptionOverLength>(() => ProtocolVersion.Value = 0x10);
            Assert.Throws<ExceptionOverLength>(() => ProtocolVersion.Value = -1);

            FactoryCode.Value = 0;
            Assert.Equal(0, FactoryCode.Value);
            Assert.Equal(5, Buffer.Count);
            Assert.Equal("0x0F", $"0x{ProtocolVersion.Value:X2}");
            Assert.Equal(0, FactoryCode.Value);
            Assert.Equal(FrameTypeEnum.NULL, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            // Assert.Equal("0x130", $"0x{CRC.Value:X2}");

            FactoryCode.Value = 0xF;
            Assert.Equal(5, Buffer.Count);
            Assert.Equal(0xF, ProtocolVersion.Value);
            Assert.Equal(0xF, FactoryCode.Value);
            Assert.Equal(FrameTypeEnum.NULL, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            // Assert.Equal(0x130, CRC.Value);

            Assert.Throws<ExceptionOverLength>(() => { FactoryCode.Value = 0x10; });
            Assert.Throws<ExceptionOverLength>(() => { FactoryCode.Value = -1; });

            Assert.Equal(FrameTypeEnum.NULL, FrameType.Value);
            FrameType.Value = FrameTypeEnum.NULL;
            Assert.Equal(0xF, ProtocolVersion.Value);
            Assert.Equal(0xF, FactoryCode.Value);
            Assert.Equal(FrameTypeEnum.NULL, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            // Assert.Equal(0x130, CRC.Value);

            FrameType.Value = (FrameTypeEnum)0x1F;
            Assert.Equal(0xF, ProtocolVersion.Value);
            Assert.Equal(0xF, FactoryCode.Value);
            Assert.Equal((FrameTypeEnum)0x1F, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            // Assert.Equal(0x130, CRC.Value);

            Assert.Throws<ExceptionOverLength>(() => FrameType.Value = (FrameTypeEnum)0x20);
            Assert.Throws<ExceptionOverLength>(() => FrameType.Value = (FrameTypeEnum)(-1));

            Assert.Equal(0, InfoLength.Value);
            InfoLength.Value = 0x7FF;
            Assert.Equal(0xF, ProtocolVersion.Value);
            Assert.Equal(0xF, FactoryCode.Value);
            Assert.Equal((FrameTypeEnum)0x1F, FrameType.Value);
            Assert.Equal(0x7FF, InfoLength.Value);
            // Assert.Equal(0x130, CRC.Value);

            InfoLength.Value = 0;
            Assert.Equal(0xF, ProtocolVersion.Value);
            Assert.Equal(0xF, FactoryCode.Value);
            Assert.Equal((FrameTypeEnum)0x1F, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            // Assert.Equal(0x130, CRC.Value);

            Assert.Throws<ExceptionOverLength>(() => InfoLength.Value = 0x800);
            Assert.Throws<ExceptionOverLength>(() => InfoLength.Value = -1);

            // Assert.Equal(0x130, CRC.Value);
            CRC.Value = 0xFFFF;
            Assert.Equal(0xF, ProtocolVersion.Value);
            Assert.Equal(0xF, FactoryCode.Value);
            Assert.Equal((FrameTypeEnum)0x1F, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            Assert.Equal(0xFFFF, CRC.Value);

            CRC.Value = 0;
            Assert.Equal(0xF, ProtocolVersion.Value);
            Assert.Equal(0xF, FactoryCode.Value);
            Assert.Equal((FrameTypeEnum)0x1F, FrameType.Value);
            Assert.Equal(0, InfoLength.Value);
            Assert.Equal(0, CRC.Value);
        }

        void SetPropertyToMin()
        {
            ProtocolVersion.Value = 0;
            FactoryCode.Value = 0x0;
            FrameType.Value = (FrameTypeEnum)0;
            InfoLength.Value = 0;
            CRC.Value = 0;
        }

        void SetPropertyToMax()
        {
            ProtocolVersion.Value = 0xF;
            FactoryCode.Value = 0xF;
            FrameType.Value = (FrameTypeEnum)0x1F;
            InfoLength.Value = 0x7FF;
            CRC.Value = 0xFFFF;
        }

        void AssertPropertyMin()
        {
            Assert.True(Buffer.Count == 5);
            Assert.True(ProtocolVersion.Value == 0);
            Assert.True(FactoryCode.Value == 0);
            Assert.True(FrameType.Value == (FrameTypeEnum)0);
            Assert.True(InfoLength.Value == 0);
            Assert.True(CRC.Value == 0);
        }

        void AssertPropertyMax()
        {
            Assert.True(Buffer.Count == 5);
            Assert.True(ProtocolVersion.Value == 0xF);
            Assert.True(FactoryCode.Value == 0xF);
            Assert.True(FrameType.Value == (FrameTypeEnum)0x1F);
            Assert.True(InfoLength.Value == 0x7FF);
            Assert.True(CRC.Value == 0xFFFF);
        }
    }
}
